home *** CD-ROM | disk | FTP | other *** search
/ Mac Power 1996 September / MACPOWER-1996-09.ISO.7z / MACPOWER-1996-09.ISO / 第2特集:プラグイン大集合 / PIC2 Save / p2save.c < prev    next >
Text File  |  1995-01-16  |  18KB  |  862 lines

  1. /*
  2.  *    PIC2 高圧縮/ベタフォーマットの展開 by やなぎさわ
  3.  *
  4.  */
  5.  
  6.  
  7. #include "pic2.h"
  8.  
  9. /* 現在のP2の中の変数のコピー (^^; */
  10.  
  11. static ushort aa;
  12. static ushort cc;
  13. static char cache_hit_c;
  14. static ushort bit_buf;
  15. static long  n_bit;
  16. static short n_bit_buf;
  17. static long xw;
  18. static long ymax;
  19. static uchar *fbufp;
  20. static long n_fbuf;
  21. static P2 *p2;
  22. static pix *vram_prev;
  23. static pix *vram_now;
  24. static pix *vram_next;
  25. static schar *flag_now;
  26. static schar *flag_next;
  27. static schar *flag2_now;
  28. static schar *flag2_next;
  29. static schar *flag2_next2;
  30. static pix  (_HUGE_ * cache)[N_COLOR_CACHE+1];
  31. static ushort *cache_pos;
  32. static ushort *mulu_tab;
  33. static long *c_sum,*c_0_sum;
  34. static char press_pass;
  35.  
  36. static short ynow;
  37.  
  38. static pix (*write_color)( pix x);
  39.  
  40. /* エラー時の脱出用 */
  41. static jmp_buf jmp_env;
  42.  
  43. /*
  44.  * 1バイトファイルに書き出し
  45.  */
  46. static void
  47. write_byte( uchar a)
  48. {
  49.     *fbufp++ = a;
  50.     if ( --n_fbuf <= 0) {
  51.         fbufp = p2->fbuf;
  52.         n_fbuf = N_FBUF;
  53.         if ( write_file( p2, fbufp, N_FBUF) != N_FBUF) {
  54.             p2errno = p2->errno = dskFulErr; //ENOSPC;
  55.             longjmp( jmp_env, 1);
  56.         }
  57.     }
  58. }
  59.  
  60. /*
  61.  * 1ビットファイルに出力 (繰り上げ対策付き)
  62.  *
  63.  * 繰り上げ対策のためにすぐには書き出さない
  64.  * そのために'0'の次に'1'が n_bitつづいている事を覚えていて
  65.  * そこに'0'が来ると、前の'0'を出してn_bitだけ'1'を出す
  66.  *       '1'が来ると、n_bitを増やす
  67.  * ただし、'0'が有無を'have_zero'にとっておく
  68.  */
  69. static char have_zero;
  70.  
  71. #define    bit_nz_write()    (n_bit++)
  72.  
  73. static void
  74. bit_z_write( void)
  75. {
  76.     long    i;
  77.  
  78.     if ( have_zero) {
  79.         bit_buf = bit_buf + bit_buf;    /* bitバッファに'0'を入れる */
  80.         if ( ++n_bit_buf == 8) {    /* bitバッファがフルなら書き出す */
  81.             write_byte( bit_buf);
  82.             n_bit_buf = 0;
  83.         }
  84.     }
  85.     for ( i = 0; i < n_bit; i++) {        /* n_bitだけ'1'があるので、それを書きだす */
  86.         bit_buf = bit_buf + bit_buf + 1;
  87.         if ( ++n_bit_buf == 8) {
  88.             write_byte( bit_buf);
  89.             n_bit_buf = 0;
  90.         }
  91.     }
  92.     have_zero = 1;
  93.     n_bit = 0;
  94. }
  95.  
  96. /* 繰り上げ */
  97. static void
  98. bit_up( void)
  99. {
  100.     bit_buf = bit_buf + bit_buf + 1;    /* 今までとっておいた'0'が繰り上がり'1'になる */
  101.     if ( ++n_bit_buf == 8) {
  102.         write_byte( bit_buf);
  103.         n_bit_buf = 0;
  104.     }
  105.     if ( n_bit == 0) {
  106.         have_zero = 0;
  107.     } else {
  108.         long i;
  109.  
  110.         for ( i = 0; i < n_bit - 1; i++) {    /* n_bitだけあった'1'は繰り上げで'0'になってしまう */
  111.             bit_buf = bit_buf + bit_buf;
  112.             if ( ++n_bit_buf == 8) {
  113.                 write_byte( bit_buf);
  114.                 n_bit_buf = 0;
  115.             }
  116.         }
  117.         have_zero = 1;
  118.     }
  119.     n_bit = 0;
  120. }
  121.  
  122. /*
  123.  *  ビットのバッファのフラッシュ
  124.  */
  125. static void
  126. bit_buf_flush( void)
  127. {
  128.     long    i;
  129.  
  130.     for ( i = 0; i < 16; i++) {
  131.         if ( cc & 0x8000) bit_nz_write();
  132.         else bit_z_write();
  133.         cc = cc + cc;
  134.     }
  135.     bit_z_write();
  136.     bit_buf <<= 8 - n_bit_buf;
  137.     write_byte(bit_buf);
  138. }
  139.  
  140. /*
  141.  * ファイルバッファのフラッシュ
  142.  */
  143. static void
  144. fbuf_flush( void)
  145. {
  146.     long n;
  147.  
  148.     bit_buf_flush();
  149.     n = N_FBUF - n_fbuf;
  150.     if ( write_file( p2, p2->fbuf, n) != n) {
  151.         longjmp( jmp_env, 1);
  152.     }
  153. }
  154.  
  155.  
  156. /*
  157.  *  算術圧縮 確率空間 'c'で 'n'(0 or 1)を符号化
  158.  */
  159. static void
  160. bit_encode( long n, long c)
  161. {
  162.     ushort pp;
  163.  
  164.     if ( press_pass  == 0) {
  165.         c_sum[c]++;
  166.         if ( n == 0) c_0_sum[c]++;
  167.         return;
  168.     }
  169.  
  170.     pp = mulu_tab[(aa & 0x7f00) / 2 + c];
  171.     if ( n != 0) {
  172.         ulong lcc = (ulong)cc + pp;
  173.         if ( lcc >= 0x10000) {
  174.             bit_up();
  175.         }
  176.         cc = lcc;
  177.  
  178.         aa = aa - pp;
  179.         while ( aa < 0x8000u) {
  180.             if ( cc & 0x8000) bit_nz_write();
  181.             else bit_z_write();
  182.             cc *= 2;
  183.             aa *= 2;
  184.         }
  185.     } else {
  186.         aa = pp;
  187.  
  188.         while ( aa < 0x8000u) {
  189.             if ( cc & 0x8000) bit_nz_write();
  190.             else bit_z_write();
  191.             cc *= 2;
  192.             aa *= 2;
  193.         }
  194.     }
  195. }
  196.  
  197. /*
  198.  *  1バイト(多値)データの符号化 上限付き
  199.  */
  200. static void
  201. nbyte_encode( long n, long c, long max)
  202. {
  203.     short    i;
  204.  
  205.     for ( i = 0; i < n; i++) {
  206.         bit_encode( 0, c + i);
  207.     }
  208.     if ( n < max) bit_encode( 1, c + n);
  209. }
  210.  
  211. /*
  212.  * nを空間cで記録
  213.  */
  214. static void
  215. nn_encode( long n, long c)
  216. {
  217.     if ( n < 1) {
  218.         bit_encode( 1, c);
  219.     } else if ( n < 1 + 2) {
  220.         bit_encode( 0, c);
  221.         bit_encode( 1, c + 1);
  222.  
  223.         n -= 1;
  224.         bit_encode( n & 1, c + 8);
  225.  
  226.     } else if ( n < 1 + 2 + 4) {
  227.         bit_encode( 0, c);
  228.         bit_encode( 0, c + 1);
  229.         bit_encode( 1, c + 2);
  230.  
  231.         n -= 1 + 2;
  232.         bit_encode( n & 1, c + 8);
  233.         bit_encode( n & 2, c + 9);
  234.  
  235.     } else if ( n < 1 + 2 + 4 + 8) {
  236.         bit_encode( 0, c);
  237.         bit_encode( 0, c + 1);
  238.         bit_encode( 0, c + 2);
  239.         bit_encode( 1, c + 3);
  240.  
  241.         n -= 1 + 2 + 4;
  242.         bit_encode( n & 1, c + 8);
  243.         bit_encode( n & 2, c + 9);
  244.         bit_encode( n & 4, c + 10);
  245.  
  246.     } else if ( n < 1 + 2 + 4 + 8 + 16) {
  247.         bit_encode( 0, c);
  248.         bit_encode( 0, c + 1);
  249.         bit_encode( 0, c + 2);
  250.         bit_encode( 0, c + 3);
  251.         bit_encode( 1, c + 4);
  252.  
  253.         n -= 1 + 2 + 4 + 8;
  254.         bit_encode( n & 1, c + 8);
  255.         bit_encode( n & 2, c + 9);
  256.         bit_encode( n & 4, c + 10);
  257.         bit_encode( n & 8, c + 11);
  258.     } else if ( n < 1 + 2 + 4 + 8 + 16 + 32) {
  259.         bit_encode( 0, c);
  260.         bit_encode( 0, c + 1);
  261.         bit_encode( 0, c + 2);
  262.         bit_encode( 0, c + 3);
  263.         bit_encode( 0, c + 4);
  264.         bit_encode( 1, c + 5);
  265.  
  266.         n -= 1 + 2 + 4 + 8 + 16;
  267.         bit_encode( n & 1, c + 8);
  268.         bit_encode( n & 2, c + 9);
  269.         bit_encode( n & 4, c + 10);
  270.         bit_encode( n & 8, c + 11);
  271.         bit_encode( n & 16, c + 12);
  272.     } else if ( n < 1 + 2 + 4 + 8 + 16 + 32 + 64) {
  273.         bit_encode( 0, c);
  274.         bit_encode( 0, c + 1);
  275.         bit_encode( 0, c + 2);
  276.         bit_encode( 0, c + 3);
  277.         bit_encode( 0, c + 4);
  278.         bit_encode( 0, c + 5);
  279.         bit_encode( 1, c + 6);
  280.  
  281.         n -= 1 + 2 + 4 + 8 + 16 + 32;
  282.         bit_encode( n & 1, c + 8);
  283.         bit_encode( n & 2, c + 9);
  284.         bit_encode( n & 4, c + 10);
  285.         bit_encode( n & 8, c + 11);
  286.         bit_encode( n & 16, c + 12);
  287.         bit_encode( n & 32, c + 13);
  288.  
  289.     } else if ( n < 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128) {
  290.         bit_encode( 0, c);
  291.         bit_encode( 0, c + 1);
  292.         bit_encode( 0, c + 2);
  293.         bit_encode( 0, c + 3);
  294.         bit_encode( 0, c + 4);
  295.         bit_encode( 0, c + 5);
  296.         bit_encode( 0, c + 6);
  297.         bit_encode( 1, c + 7);
  298.  
  299.         n -= 1 + 2 + 4 + 8 + 16 + 32 + 64;
  300.         bit_encode( n & 1, c + 8);
  301.         bit_encode( n & 2, c + 9);
  302.         bit_encode( n & 4, c + 10);
  303.         bit_encode( n & 8, c + 11);
  304.         bit_encode( n & 16, c + 12);
  305.         bit_encode( n & 32, c + 13);
  306.         bit_encode( n & 64, c + 14);
  307.     } else {
  308.         bit_encode( 0, c);
  309.         bit_encode( 0, c + 1);
  310.         bit_encode( 0, c + 2);
  311.         bit_encode( 0, c + 3);
  312.         bit_encode( 0, c + 4);
  313.         bit_encode( 0, c + 5);
  314.         bit_encode( 0, c + 6);
  315.         bit_encode( 0, c + 7);
  316.     }
  317. }
  318.  
  319. /*
  320.  * 連鎖の符号化
  321.  */
  322. static void
  323. press_chain( long x)
  324. {
  325.     long d = 0;
  326.     long b = -flag_now[ x];    /* 現在の点の確率空間は、この点がどこの連鎖だったかによる */
  327.     pix c = vram_now[x];
  328.  
  329.     if ( b < 0) b = 0;
  330.  
  331.     /* 左右の境界チェックが無いけど、flagの配列を左右余分にとってあり、それが0なので
  332.      * 特別に (x - 1 < 0)などのチェックはしていない
  333.      */
  334.     if ( flag_next[ x] == 1 && vram_next[ x] == c) {
  335.         d = 1;
  336.         flag_next[ x] = -1;
  337.     } else if ( flag_next[ x - 1] == 1 && vram_next[ x - 1] == c) {
  338.         d = 2;
  339.         flag_next[ x - 1] = -2;
  340.     } else if ( flag_next[ x + 1] == 1 && vram_next[ x + 1] == c) {
  341.         d = 3;
  342.         flag_next[ x + 1] = -3;
  343.     } else if ( flag_next[ x - 2] == 1 && vram_next[ x - 2] == c) {
  344.         d = 4;
  345.         flag_next[ x - 2] = -4;
  346.     } else     if ( flag_next[ x + 2] == 1 && vram_next[ x + 2] == c) {
  347.         /* 右2つは出来るだけ作らないようにする。下の条件にマッチすれば
  348.          * 今連鎖を取らなくても数画素後に連鎖となる。
  349.          */
  350.         if (  (flag_now[ x + 2] != 0 && vram_now[ x + 2] == c)
  351.            || (flag_now[ x + 1] != 0 && vram_now[ x + 1] == c)
  352.            || (flag_now[ x + 3] != 0 && vram_now[ x + 3] == c)
  353.         ) {    /* なしね */
  354.  
  355.             nbyte_encode( 0, 80 + 6 * b, 5);
  356.             return;
  357.         }
  358.         d = 5;
  359.         flag_next[ x + 2] = -5;
  360.     }
  361.     nbyte_encode( d, 80 + 6 * b, 5);
  362. }
  363.  
  364. /*
  365.  * 16bit色の書き出し
  366.  */
  367. static void
  368. write_color8( uchar cc)
  369. {
  370.     short    i,j;
  371.     uchar *cache8 = (uchar *)cache_pos;
  372.     
  373.     for ( i = 0; i < 256; i++) {
  374.         if ( cache8[i] == cc) break;
  375.     }
  376.     nn_encode( i, 32);
  377.     for ( j = i; j > 0; j--) {
  378.         cache8[ j] = cache8[ j - 1];
  379.     }
  380.     cache8[ 0] = cc;
  381. }
  382.  
  383.  
  384. #define    N_CACHE8_S    5
  385. #define N_CACHE8    ((1<<N_CACHE8_S)-1)
  386.  
  387. static void
  388. write_color16( pix x)
  389. {
  390.     pix    cc,*p,*pp;
  391.     short    i,j,k;
  392.  
  393.     k = vram_now[ x - 1] & 255;
  394.     cc = vram_now[ x];
  395.  
  396.     p = cache[k];
  397.     for ( i = 0; i < N_CACHE8; i++) {
  398.         if ( cc == *p++) break;
  399.     }
  400.     if ( i == N_CACHE8) {
  401.         pp = p - 1;
  402.         for ( j = N_CACHE8; j > 0; j--) {
  403.             *--p = *--pp;
  404.         }
  405.  
  406.         cache[ k][0] = cc;
  407.         bit_encode( 1, cache_hit_c);
  408.         cache_hit_c = 16;
  409.  
  410.         write_color8( cc >> 8);
  411.         write_color8( cc & 255);
  412.     } else {
  413.         /* *--p = cache[k][i/2]; */
  414.         cache[k][i] = cache[k][i/2];
  415.         cache[k][i/2] = cache[k][0];
  416.         cache[k][0] = cc;
  417.         bit_encode( 0, cache_hit_c);
  418.         cache_hit_c = 15;
  419.         nn_encode( i, 17);
  420.     }
  421.     /* printf("%d/%d:%ld,%d,%d¥n", ynow - 1, x, cc, k, i); */
  422. }
  423.  
  424.  
  425. /*
  426.  *  色の符号化
  427.  */
  428. #define        putnum15( xn, xa, xb) {                ¥
  429.     short    n;                        ¥
  430.     if ( xa >= 16) {                     ¥
  431.         if ( xb > xa) n = ( xb - xa) * 2 - 1;        ¥
  432.         else if ( xa - (31 - xa)  > xb) n = 31 - xb;    ¥
  433.         else n = ( xa - xb) * 2;            ¥
  434.     } else  {                        ¥
  435.         if ( xb <= xa) n = ( xa - xb) * 2;        ¥
  436.         else if ( 2 * xa < xb) n = xb;            ¥
  437.         else n = ( xb - xa) * 2 - 1;            ¥
  438.     }                            ¥
  439.     nn_encode( n, xn);                    ¥
  440. }
  441.  
  442. static void
  443. write_color15( pix x)
  444. {
  445.     pix c1,c2,cc;
  446.     short g0,r0,b0,r,g,b;
  447.     short i,j;
  448.     ushort    k;
  449.     pix *p,*pp;
  450.  
  451.     cc = vram_now[ x];
  452.     c1 = vram_prev[ x];
  453.     k = ((c1 >> 7) & 0x1c0) + ((c1 >> 5) & 0x38) + ((c1 >> 3) & 7);
  454.  
  455.     p = cache[k];
  456.     for ( i = 0; i < N_COLOR_CACHE; i++) {
  457.         if ( cc == *p++) break;
  458.     }
  459.     if ( i == N_COLOR_CACHE) {
  460.         pp = p - 1;
  461.         for ( j = i; j > 0; j--) {
  462.             *--p = *--pp;
  463.         }
  464.         cache[ k][ 0] = cc;
  465.         bit_encode( 1, cache_hit_c);
  466.         cache_hit_c = 16;
  467.  
  468.         c2 = vram_now[ x - 1];
  469.  
  470.         g = ((c1 & 0xf800u) + (c2 & 0xf800u)) >> 12;
  471.         r = ((c1 & 0x07c0u) + (c2 & 0x07c0u)) >>  7;
  472.         b = ((c1 & 0x003eu) + (c2 & 0x003eu)) >>  2;
  473.         g0 = (cc >> 11) & 31;
  474.         r0 = (cc >> 6) & 31;
  475.         b0 = (cc >> 1) & 31;
  476.  
  477.         r = r + g0 - g;
  478.         if ( r < 0) r = 0;
  479.         else if ( r > 31) r = 31;
  480.  
  481.         b = b + g0 - g;
  482.         if ( b < 0) b = 0;
  483.         else if ( b > 31) b = 31;
  484.  
  485.         putnum15( 32, g, g0);
  486.         putnum15( 48, r, r0);
  487.         putnum15( 64, b, b0);
  488.  
  489.     } else {
  490.         *--p = cache[k][i/2];
  491.         cache[k][i/2] = cache[k][0];
  492.         cache[ k][ 0] = cc;
  493.  
  494.         bit_encode( 0, cache_hit_c);
  495.         cache_hit_c = 15;
  496.         nn_encode( i, 17);
  497.  
  498.     }
  499. }
  500.  
  501. #define        putnum24( xn, xa, xb) {                ¥
  502.     short    n;                        ¥
  503.     if ( xa >= 128) {                     ¥
  504.         if ( xb > xa) n = ( xb - xa) * 2 - 1;        ¥
  505.         else if ( xa - (255 - xa)  > xb) n = 255 - xb;    ¥
  506.         else n = ( xa - xb) * 2;            ¥
  507.     } else  {                        ¥
  508.         if ( xb <= xa) n = ( xa - xb) * 2;        ¥
  509.         else if ( 2 * xa < xb) n = xb;            ¥
  510.         else n = ( xb - xa) * 2 - 1;            ¥
  511.     }                            ¥
  512.     nn_encode( n, xn);                    ¥
  513. }
  514.  
  515. static void
  516. write_color24( pix x)
  517. {
  518.     pix c1,c2,cc;
  519.     long g0,r0,b0,r,g,b;
  520.     long i,j,k;
  521.     pix *p,*pp;
  522.  
  523.     cc = vram_now[ x];
  524.     c1 = vram_prev[ x];
  525.  
  526.     /* RRRrrrrrGGGgggggBBBbbbbb -> RRRGGGBBB */
  527.     k =   (c1 >> (16 + 5 - 6) & 0x1c0)    /* red */
  528.         + (c1 >> ( 8 + 5 - 3) & 0x038)    /* green */
  529.         + (c1 >> ( 0 + 5 - 0) & 0x007);    /* blue */
  530.  
  531.     p = cache[k];
  532.     for ( i = 0; i < N_COLOR_CACHE; i++) {
  533.         if ( cc == *p++) break;
  534.     }
  535.     if ( i == N_COLOR_CACHE) {
  536.         pp = p - 1;
  537.         for ( j = i; j > 0; j--) {
  538.             *--p = *--pp;
  539.         }
  540.         cache[ k][ 0] = cc;
  541.         bit_encode( 1, cache_hit_c);
  542.         cache_hit_c = 16;
  543.  
  544.         c2 = vram_now[ x - 1];
  545.  
  546.         g = ((c1 & 0x00ff00u) + (c2 & 0x00ff00u)) >> (8 + 1);
  547.         r = ((c1 & 0xff0000u) + (c2 & 0xff0000u)) >> (16 + 1);
  548.         b = ((c1 & 0x0000ffu) + (c2 & 0x0000ffu)) >> (0 + 1);
  549.  
  550.         g0 = (cc >> 8) & 255;
  551.         r0 = (cc >> 16) & 255;
  552.         b0 = cc & 255;
  553.  
  554.         r = r + g0 - g;
  555.         if ( r < 0) r = 0;
  556.         else if ( r > 255) r = 255;
  557.  
  558.         b = b + g0 - g;
  559.         if ( b < 0) b = 0;
  560.         else if ( b > 255) b = 255;
  561.  
  562.         putnum24( 32, g, g0);
  563.         putnum24( 48, r, r0);
  564.         putnum24( 64, b, b0);
  565.     } else {
  566.         *--p = cache[k][i/2];
  567.         cache[k][i/2] = cache[k][0];
  568.         cache[ k][ 0] = cc;
  569.  
  570.         bit_encode( 0, cache_hit_c);
  571.         cache_hit_c = 15;
  572.         nn_encode( i, 17);
  573.     }
  574. }
  575.  
  576.  
  577. /* 構造体アクセスをケチするため */
  578.  
  579. static void
  580. para_out( void)
  581. {
  582.     fbufp = p2->fbufp;
  583.     n_fbuf = p2->n_fbuf;
  584.     bit_buf = p2->bit_buf;
  585.     n_bit_buf = p2->n_bit_buf;
  586.     n_bit = p2->data;
  587.     ymax = SHORT2short( p2->blk.y_wid) - 1;
  588.     xw = SHORT2short( p2->blk.x_wid);
  589.     aa = p2->aa;
  590.     cc = p2->cc;
  591.     press_pass = p2->dd;
  592.     cache_hit_c = p2->cache_hit_c;
  593.     write_color = (pix (*)(pix))p2->func;
  594.     ynow = p2->ynow;
  595.     vram_prev = p2->vram_prev + 4;
  596.     vram_now = p2->vram_now + 4;
  597.     vram_next = p2->vram_next + 4;
  598.     flag_now = p2->flag_now + 4;
  599.     flag_next = p2->flag_next + 4;
  600.     flag2_now = p2->flag2_now + 4;
  601.     flag2_next = p2->flag2_next + 4;
  602.     flag2_next2 = p2->flag2_next2 + 4;
  603.      cache = p2->cache;
  604.     mulu_tab = p2->mulu_tab;
  605.     c_sum = (long *)mulu_tab;
  606.     c_0_sum = c_sum + N_CONTEXT + 1;
  607.     cache_pos = p2->cache_pos;
  608. }
  609.  
  610. static void
  611. para_in( void)
  612. {
  613.     void *p;
  614.     
  615.     p2->fbufp = fbufp;
  616.     p2->n_fbuf = n_fbuf;
  617.     p2->bit_buf = bit_buf;
  618.     p2->n_bit_buf = n_bit_buf;
  619.     p2->data = n_bit;
  620.     p2->aa = aa;
  621.     p2->cc = cc;
  622.     p2->dd = press_pass;
  623.     p2->cache_hit_c = cache_hit_c;
  624.     p2->func = (pix (*)(pix))write_color;
  625.  
  626.     p = p2->vram_prev;
  627.     p2->vram_prev = p2->vram_now;
  628.     p2->vram_now = p2->vram_next;
  629.     p2->vram_next = p;
  630.  
  631.     p = p2->flag_now;
  632.     p2->flag_now = p2->flag_next;
  633.     p2->flag_next = p;
  634.     
  635.     p = p2->flag2_now;
  636.     p2->flag2_now = p2->flag2_next;
  637.     p2->flag2_next = p2->flag2_next2;
  638.     p2->flag2_next2 = p;
  639.  
  640.     p2->ynow = ynow;
  641. }
  642.  
  643. /*
  644.  * 1行 圧縮
  645.  */
  646. static void
  647. line_press2( void)
  648. {
  649.     short x;
  650.     long a;
  651.     pix cc;
  652.     
  653.     if ( SHORT2short( p2->header.depth) == 8) {
  654.         cc = vram_now[ xw * 2 - 2];
  655.         cc = cc * 256 + vram_now[ xw * 2 - 1];
  656.     } else {
  657.         cc = vram_now[ xw - 1];    /* ひとつ前の色 */
  658.     }
  659.     vram_next[ -1] = cc;
  660.     
  661.     /* 変化点をマーク */
  662.     for ( x = 0; x < xw; x++) {
  663.         pix c = vram_next[ x];
  664.         if ( cc != c) {
  665.             flag_next[ x] = 1;
  666.             cc = c;
  667.         } else flag_next[ x] = 0;
  668.     }
  669.  
  670.     for ( x = 0; x < xw; x++) {
  671.         a = flag_now[ x];
  672.  
  673.         if ( a == 1) {    /* 変化点 */
  674.  
  675.             /* 変化点の回りに変化点は多くなるので */
  676.             flag2_now[ x + 1]++;    flag2_now[ x + 2]++;
  677.             flag2_next[  x - 1]++;    flag2_next[  x    ]++;    flag2_next[  x + 1]++;
  678.             flag2_next2[ x - 1]++;    flag2_next2[ x    ]++;    flag2_next2[ x + 1]++;
  679.  
  680.             /* 回りの変化点の多さで確率空間を切替えて、変化点の位置を記録 */
  681.             bit_encode( 1, flag2_now[ x]);
  682.             /* 色を記録 */
  683.             write_color( x);
  684.  
  685.             /* 一番下でなければ連鎖を記録
  686.              * (ynow は実際にセーブしているライン+1が入っている)
  687.              */
  688.             if ( ynow - 1 < ymax) press_chain( x);
  689.  
  690.         } else if ( a == 0) { /* 連鎖上でない */
  691.             /* 回りの変化点の多さで確率空間を切替えて記録 */
  692.             bit_encode( 0, flag2_now[ x]);
  693.  
  694.         } else { /* 連鎖上 */
  695.             /* 一番下でなければ次の連鎖を記録 */
  696.             if ( ynow - 1 < ymax) press_chain( x);
  697.         }
  698.     }    
  699. }
  700.  
  701. /*
  702.  * 行単位の圧縮で最初/最終ラインの処理をする
  703.  */
  704. long
  705. line_press( P2 *pp2, pix **line)
  706. {
  707.     if ( setjmp( jmp_env) != 0) return ( -1);
  708.     p2 = pp2;
  709.     para_out();
  710.  
  711.     if ( SHORT2short( pp2->header.depth) == 8) {
  712.         short i,j;
  713.  
  714.         xw = (xw + 1) / 2;
  715.         for ( i = j = 0; i < xw; i++) {
  716.             ushort hi = vram_next[ j++];
  717.             ushort low = vram_next[ j++];
  718.             
  719.             vram_next[ i] = hi * 256 + low;
  720.         }
  721.     }
  722.     
  723.  
  724.     memset( flag2_next2 - 4, 0, (8 + xw) * sizeof( flag2_next2[0]));
  725.  
  726.     if ( ynow == 0) { /* 先頭ラインの時 */
  727.         short x,i;
  728.         pix ccc;
  729.  
  730.         if ( press_pass != 0) { /* 圧縮 pass */
  731.             unsigned short c_tab[N_CONTEXT];
  732.  
  733. /*            fprintf( stderr, "press pass¥n");*/
  734.             for ( i = 0; i < N_CONTEXT; i++) {
  735.                 ulong a, b;
  736.                 a = c_0_sum[i];
  737.                 b = c_sum[i];
  738.                 while ( a > 32767) { /* 下で65536掛けた時に溢れないように */
  739.                     a >>= 1;
  740.                     b >>= 1;
  741.                 }
  742.                 if ( a == b) c_tab[i] = 0xffffu; /* b==0 もここになる */
  743.                 else c_tab[i] = (65536uL * a) / b; /* a < b なので 65536以下 */
  744.             }
  745.             for ( i = 0; i < 16384; i++) {
  746.                 mulu_tab[i] = (ulong)((i >> 7) + 128) * c_tab[i & 127] / 256;
  747.                 if ( mulu_tab[i] == 0) mulu_tab[i] = 1; /* 0があるとだめだから */
  748.             }
  749.             p2errno = 0;
  750.             for ( i = 0; i < N_CONTEXT; i++) {
  751.                 write_short( p2, c_tab[i]);
  752.             }
  753.             if ( p2errno != 0) return ( -1);
  754.             memset( vram_now, 0, xw * sizeof( vram_now[0]));
  755.         } else { /* 統計 pass */
  756.             memset( c_0_sum, 0, N_CONTEXT * sizeof( c_0_sum[0]));
  757.             memset( c_sum, 0, N_CONTEXT * sizeof( c_sum[0]));
  758.         }
  759.  
  760.         /* フラグなどの初期化 */
  761.         l_memset( cache, 0, 8 * 8 * 8 * (long)sizeof( cache[0]));
  762.         memset( flag2_next - 4, 0, (8 + xw) * sizeof( flag2_next[0]));
  763.         memset( flag2_next2 - 4, 0, (8 + xw) * sizeof( flag2_next2[0]));
  764.  
  765.         for ( i = 0; i < 256; i++) {
  766.             uchar *p = (uchar *)cache_pos;
  767.             p[i] = i;
  768.         }
  769.  
  770.         vram_next[ -1] = ccc = 0;
  771.         for ( x = 0; x < xw; x++) {
  772.             pix c = vram_next[ x];
  773.             if ( ccc != c) {
  774.                 flag_next[ x] = 1;
  775.                 ccc = c;
  776.             } else flag_next[ x] = 0;
  777.         }
  778.         aa = 0xffff;
  779.         cc = 0;
  780.         n_bit = 0;
  781.  
  782.         fbufp = p2->fbuf;
  783.         n_fbuf = N_FBUF;
  784.         n_bit_buf = 0;
  785.         bit_buf = 0;
  786.         have_zero = 0;
  787.         cache_hit_c = 16;
  788.     } else { /* 2ライン目から実際にセーブをする。これは1ライン先のデータが必要だから */
  789.  
  790.         line_press2();
  791.     }
  792.     if ( ynow ==  ymax) {
  793.         /* 最後のラインの時は次のラインはもう無いので、これをセーブ */
  794.         ynow++;
  795.         para_in();
  796.         para_out();
  797.         if ( SHORT2short( pp2->header.depth) == 8) xw = (xw + 1) / 2;
  798.         
  799.         line_press2();
  800.     }
  801.     /* 次のデータを入れて欲しいライン (vram_prevは次回 vram_nextになる)*/
  802.     if ( line != NULL) *line = vram_prev;
  803.  
  804.     ynow++;
  805.  
  806.     if ( ynow - 1 < ymax) { /* 最終ライン(終り)でなければ */
  807.         para_in();    /* P2にパラメータ入れる(戻す) */
  808.         return ( ynow);
  809.     } else {    /* おわり */
  810.         if ( press_pass == 0) { /* 統計パス */
  811.             press_pass = 1; /* 次回から圧縮パス */
  812.             ynow = 0;
  813.             para_in();    /* P2にパラメータ入れる(戻す) */
  814.             return ( 0);    /* 次回は圧縮パスだよん */
  815.         } else {
  816.             para_in();    /* P2にパラメータ入れる(戻す) */
  817.             p2errno = 0;
  818.             fbuf_flush(); /* bitバッファを書き出して */
  819.             
  820.             return ( -2);    /* おわり */
  821.         }
  822.     }
  823. }
  824.  
  825. /*
  826.  * 算術圧縮部の初期化
  827.  */
  828. long
  829. p2ss_sv_init( P2 *p2, pix **line)
  830. {
  831.     p2->ynow = 0;
  832.  
  833.     /* 色の記録関数のセット */
  834.     switch ( SHORT2short( p2->header.depth)) {
  835.     case 24:
  836.         p2->func = (pix (*)())write_color24;
  837.         break;
  838.     case 15:
  839.         p2->func = (pix (*)())write_color15;
  840.         break;
  841.     case 8:
  842.         p2->func = (pix (*)())write_color16;
  843.         break;
  844.     default:
  845.         p2errno= p2->errno = P2E_BADFORM;
  846.         return ( -1);
  847.     }
  848.  
  849.     /* 次ライン関数をセット */
  850.     p2->nextline = line_press;
  851.  
  852.     if ( line != NULL) *line = p2->vram_next + 4;
  853.     p2errno = 0;
  854.     seek_file( p2, p2->next_pos + SIZE_OF_BLK);
  855.     if ( p2errno == 0) return ( 0);
  856.     return ( -1);
  857. }
  858.  
  859. /* eof */
  860.  
  861.  
  862.